from openpyxl import load_workbook

from django.http import HttpResponse, JsonResponse
from django.core.serializers import serialize
from django.core.cache import cache

from ...models.users import Users
from ...models.chat_redeem import Redeem
from ...models.configs import Configs
from ...models.powerlogs import PowerLogs

from ...utils.data_handle import chatredeem_handler, generate_random_string
from ...utils.users import get_login_user_id
from ...utils.time_conversion import datetime_to_times
from ...utils.data_handle import users_data_paging

import io
import json
import datetime
import pandas as pd


def redeem_list(request):
    '''
    卡密管理-兑换码
    参数：
    code=&status=-1&page=1&page_size=12

    data = {
        "id": 2,
        "user_id": 0,
        "name": "100算力点卡",
        "username": "",
        "power": 100,
        "code": "a08679cef5814c316d952f42aff2ed99",
        "enabled": true,
        "redeemed_at": 0,
        "created_at": 1729667030
        "status": 0
    }
    '''
    get_params = request.GET.dict()

    # 获取用户提交过来需要查询的参数
    search_dict = dict()

    if "code" in get_params and get_params['code']:
        search_dict["code"] = get_params['code']

    if int(get_params['status']) != -1:
        search_dict["status"] = get_params['status']

    # 获取所有的兑换码
    all_chatredeem = Redeem.objects.filter(**search_dict).order_by('-id')
    all_chatredeem_data = chatredeem_handler(all_chatredeem, get_params['page'], get_params['page_size'])

    res_mes = {
        "code": 0,
        "data": all_chatredeem_data
    }
    res_mes_json = json.dumps(res_mes, ensure_ascii=False)
    return HttpResponse(res_mes_json)


def redeem_generate(request):
    '''
    卡密管理-生成兑换码
    {
        "name": "100算力点卡",
        "power": 100,
        "quantity": 1
    }
    '''

    if request.method == 'POST':
        json_b = request.body
        json_str = json_b.decode('utf-8')
        json_obj = json.loads(json_str)

        # 获取系统配置
        chat_config_json = Configs.objects.get(marker="system").config_json

        if "name" in json_obj:
            if not json_obj['name']:
                res_mes = {
                    "code": 1,
                    "message": "参数错误！"
                }
                res_mes_json = json.dumps(res_mes, ensure_ascii=False)
                return HttpResponse(res_mes_json)
        else:
            res_mes = {
                "code": 1,
                "message": "参数错误！"
            }
            res_mes_json = json.dumps(res_mes, ensure_ascii=False)
            return HttpResponse(res_mes_json)

        if "power" in json_obj:
            if not json_obj['power']:
                json_obj['power'] = chat_config_json['init_power']
        else:
            json_obj['power'] = chat_config_json['init_power']

        if "quantity" in json_obj:
            if not json_obj['quantity']:
                json_obj['quantity'] = 1
        else:
            json_obj['quantity'] = 1
        

        # 生成兑换码
        '''
        data = {
            "id": 2,
            "user_id": 0,
            "name": "100算力点卡",
            "username": "",
            "power": 100,
            "code": "a08679cef5814c316d952f42aff2ed99",
            "enabled": true,
            "redeemed_at": 0,
            "created_at": 1729667030
            "status": 0
        }
        '''

        redeem_obj_list = []
        for _ in range(json_obj['quantity']):
            redeem_obj_list.append(Redeem(
                name = json_obj['name'],
                power = json_obj['power'],
                code = generate_random_string(),
            ))

        # 使用 bulk_create() 方法批量插入数据
        try:
            Redeem.objects.bulk_create(redeem_obj_list)

            res_mes = {
                "code": 0,
                "data": {
                    "counter": json_obj['quantity']
                }
            }
            res_mes_json = json.dumps(res_mes, ensure_ascii=False)
            return HttpResponse(res_mes_json)
        except:
            res_mes = {
                "code": 1,
                "message": "生成失败！"
            }
            res_mes_json = json.dumps(res_mes, ensure_ascii=False)
            return HttpResponse(res_mes_json)


def redeem_enable(request):
    '''
    post
    body = {
        "id": 3,
        "enabled": true
    }
    '''

    if request.method == 'POST':
        json_b = request.body
        json_str = json_b.decode('utf-8')
        json_obj = json.loads(json_str)

        try:
            Redeem.objects.filter(id=json_obj['id']).update(enabled=json_obj['enabled'])
        except Exception as e:
            res_mes = {
                "code": 1,
                "message": "数据保存失败！"
            }
            res_mes_json = json.dumps(res_mes, ensure_ascii=False)
            return HttpResponse(res_mes_json)
        
        res_mes = {
            "code": 0
        }
        res_mes_json = json.dumps(res_mes, ensure_ascii=False)
        return HttpResponse(res_mes_json)


def redeem_remove(request):
    '''
    删除卡密
    id=1
    '''
    re_id = request.GET.get('id')
    try:
        del_obj = Redeem.objects.get(id=re_id)
        del_obj.delete()

        res_mes = {
            "code": 0
        }
        res_mes_json = json.dumps(res_mes, ensure_ascii=False)
        return HttpResponse(res_mes_json)
    except Exception as e:
        res_mes = {
            "code": 1,
            "message": "数据删除失败！"
        }
        res_mes_json = json.dumps(res_mes, ensure_ascii=False)
        return HttpResponse(res_mes_json)


def redeem_export(request):
    '''
    导出卡密 到表格
    '''
    if request.method == 'POST':
        json_b = request.body
        json_str = json_b.decode('utf-8')
        json_obj = json.loads(json_str)

        # 指定文件名和sheet名
        file_name = 'my_data.xlsx'
        sheet_name = 'Sheet1'

        # 先查询数据
        redeem_obj = Redeem.objects.filter(id__in=json_obj)
        data_list = redeem_obj.values('name', 'code', 'power')

        # 创建DataFrame对象
        df = pd.DataFrame(list(data_list), columns=[field.name for field in Redeem._meta.fields if field.name in ['name', 'code', 'power']])

        # 创建一个BytesIO对象来保存Excel数据
        excel_data = io.BytesIO()

        # 导出数据到BytesIO对象
        df.to_excel(excel_data, index=False, sheet_name=sheet_name)

        # 重置BytesIO对象的指针到开头
        excel_data.seek(0)

        # 创建HttpResponse对象，并设置适当的头部信息
        response = HttpResponse(excel_data, content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
        response['Content-Disposition'] = 'attachment; filename={}'.format(file_name)

        # 返回HttpResponse对象
        return response


def redeem_verify(request):
    '''
    兑换码核销，核对
    post
    {
        "code": a08679cef5814c316d952f42aff2ed99
    }

    data = {
            "id": 2,
            "user_id": 0,
            "name": "100算力点卡",
            "username": "",
            "power": 100,
            "code": "a08679cef5814c316d952f42aff2ed99",
            "enabled": true,
            "redeemed_at": 0,
            "created_at": 1729667030
            "status": 0
        }
    '''
    if request.method == 'POST':
        json_b = request.body
        json_str = json_b.decode('utf-8')
        json_obj = json.loads(json_str)

        # 先查询 user_id
        userid = get_login_user_id(request, isadmin=False)
        # print(userid, "会话检测")
        if not userid:
            res_mes = {
                "code": 1,
                "message": "用户没有登陆!"
            }
            res_mes_json = json.dumps(res_mes, ensure_ascii=False)
            return HttpResponse(res_mes_json)
        
        # 获取用户信息
        user_obj = Users.objects.filter(id=userid)
        if user_obj:
            uname = user_obj[0].username
        else:
            res_mes = {
                "code": 1,
                "message": "没有此用户!"
            }
            res_mes_json = json.dumps(res_mes, ensure_ascii=False)
            return HttpResponse(res_mes_json)
        
        # 获取这个卡密数据
        redeem_obj_all = Redeem.objects.filter(code=json_obj['code'])

        if redeem_obj_all:
            redeem_obj = redeem_obj_all[0]
            # 如果是false 那这个兑换码就是没启动
            if not redeem_obj.enabled:
                res_mes = {
                    "code": 1,
                    "message": "兑换码无效!"
                }
                res_mes_json = json.dumps(res_mes, ensure_ascii=False)
                return HttpResponse(res_mes_json)

            # 如果状态为1 那就是已经被兑换了的
            if redeem_obj.status:
                res_mes = {
                    "code": 1,
                    "message": "兑换码已被核销!"
                }
                res_mes_json = json.dumps(res_mes, ensure_ascii=False)
                return HttpResponse(res_mes_json)
        else:
            res_mes = {
                "code": 1,
                "message": "没有这个兑换码!"
            }
            res_mes_json = json.dumps(res_mes, ensure_ascii=False)
            return HttpResponse(res_mes_json)
        

        # 如果前面的判断都没问题的话 那就可以进行用户算力的增加了
        # 先进行兑换码数据更新，先进行兑换码更新 防止兑换码更新失败 用户增加算力 成功的话 那就可以无限刷
        '''
        data = {
            "id": 2,
            "user_id": 0,
            "name": "100算力点卡",
            "username": "",
            "power": 100,
            "code": "a08679cef5814c316d952f42aff2ed99",
            "enabled": true,
            "redeemed_at": 0,
            "created_at": 1729667030
            "status": 0
        }
        '''
        redeem_obj.user_id = userid
        redeem_obj.username = uname
        redeem_obj.redeemed_at = datetime.datetime.now()
        redeem_obj.status = True

        try:
            redeem_obj.save()
        except:
            res_mes = {
                "code": 1,
                "message": "兑换失败，兑换码数据更新失败!"
            }
            res_mes_json = json.dumps(res_mes, ensure_ascii=False)
            return HttpResponse(res_mes_json)
        
        # 如果兑换码数据更新成功了 那么再更新用户数据
        user_obj_one = user_obj[0]
        user_obj_one.power += redeem_obj.power

        try:
            user_obj_one.save()
        except:
            res_mes = {
                "code": 1,
                "message": "兑换失败，用户数据更新失败!"
            }
            res_mes_json = json.dumps(res_mes, ensure_ascii=False)
            return HttpResponse(res_mes_json)
        
        # 更新用户算力日志 增加一条记录
        # 记录算力充值日志
        remark_str = '{}, 算力: {}, 兑换码: {}'.format("卡密兑换", redeem_obj.power, json_obj['code'])


        powerlogs_obj = PowerLogs(
            user_id = userid,
            username = uname,
            type = 7,
            amount = redeem_obj.power,
            balance = user_obj_one.power,
            model = "redeem-code",
            remark = remark_str,
            mark = 1
        )

        try:
            powerlogs_obj.save()
        except:
            pass

        # 如果一切都完成了之后 就更新用户信息到redis缓存
        # 设置用户信息缓存到redis
        # 先获取一次用户的最新数据
        try:
            chatusers_tree_json = users_data_paging(user_obj, 1, 10)
            cache.set(f'user_info_{userid}', chatusers_tree_json["items"][0], timeout=3600)  # 设置缓存超时时间为3600秒
        except:
            pass


        res_mes = {
            "code": 0,
        }
        res_mes_json = json.dumps(res_mes, ensure_ascii=False)
        return HttpResponse(res_mes_json)

